<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 约定一个 符号  这里是显示最终值的地方 -->
    <div id="box">
        <p>姓名:{{name}}</p>
        <p>年龄:{{age}}</p>
        <p>身高:{{height}}</p>
        <p>其它:{{desc}}</p>
    </div>
    <script>


        //选择器找到模板位置  
        // 数据
        // const obj = {
        //     name:'张三',
        //     age:18,
        //     height:'181cm',
        //     desc:'我爱北京天安门'
        // }

        // 数据劫持 



        // let age = 19;
        // if(age>=20){
        //     alert('欢迎光临')
        // }
        // else{
        //     // throw new Error('你太小了,回家吃饭'); // 手动抛出错误  

        // }





        // 调用的时候我们想这样调用 

        /* 函数名({
            el:'#box',
            data:{
                name:'张三',
                age:18,
                height:'181cm',
                desc:'我爱北京天安门' 
            }
        }) */


        function myvue(options={}){
            //判断用户有没有传el 没有传 抛出错误
            if(!options.el) throw new Error('您没有传递选择器');
            //到这里说明你传递了选择器 根据选择器查找元素 
            const root = document.querySelector(options.el);

            if(!root) throw new Error('您传递的选择器不正确找不到元素');

            if(!options.data) return;
            if(options.data.constructor!==Object) throw new Error('您传递的数据不是对象请重新传递');
        
            const _data = {}; // 用来劫持数据  最终被返回

            const rootDir = root.innerHTML;
            // options.data是原始数据  
            for(let k in options.data){
                Object.defineProperty(_data,k,{// 第一个参数不能是原对象
                    get(){
                        return options.data[k];
                    },
                    set(val){
                        options.data[k] = val;
                        //TODO 这里需要一个函数 如果你修改了数据 需要同步到页面上
                        render(root,_data,rootDir);
                    }
                });
            }

            // 打开页面数据同步到页面上 
            //TODO  需要一个函数 
            render(root,_data,rootDir);
            return _data;

        }
        // 将劫持的数据渲染页面上   
        // 如果数据被改 也同步到页面上
        // 为什么需要原始数据结构  后期正则替换 根据原始的替换 
        // 如果替换了 会发生变化  所以需要保存一份原始数据结构
        function render(root,_data,rootDir){
            let str = rootDir;
            // console.log(str);
            // console.log(_data);
            let reg = /{{ *(\w+) *}}/g;
            const res = str.match(reg);
            // console.log(res);

            res.forEach(item => {
                // item  {{name}} {{age}}
                //拿到key 
                //  name     根据name 从劫持的数据 拿到对应的值  替换 {{name}}
                const key = reg.exec(str)[1]; // name 
                str = str.replace(/{{ *(\w+) *}}/,_data[key]) //_data[name] 张三 替换 {{name}}
                // console.log(str);

                root.innerHTML = str;
            });

        }


        myvue({
            el:'#box',
            data:{
                name:'张三888',
                age:189,
                height:'181cm',
                desc:'我爱北京天安门9999999' 
            }
        })

    </script>
</body>
</html>